package io.mft.runtime.function.process.executor;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import io.mft.api.domain.Api;
import io.mft.api.domain.ApiRegulation;
import io.mft.api.domain.Output;
import io.mft.api.domain.OutputDs;
import io.mft.api.domain.OutputParameter;
import io.mft.api.domain.Regulation;
import io.mft.commons.function.ExecuteReturn;
import io.mft.commons.function.response.DsName;
import io.mft.commons.function.response.kv.PageObject;
import io.mft.runtime.function.ApiContext;
import io.mft.runtime.function.process.ApiFunctionProcessExecutor;

/**
 * 接口输出参数处理,只返回最后一个逻辑单元的返回结果集，其它的结果集将被移除
 * 
 * @说明：TODO
 * @类型名称：OutputParameterProcessExecutor
 * @创建者: 胡常建
 * @创建时间: 2021年3月5日 下午3:11:16
 * @修改者: 胡常建
 * @修改时间: 2021年3月5日 下午3:11:16
 */
public class OutputParameterProcessExecutor extends ApiFunctionProcessExecutor<Regulation> {

	@Override
	public ExecuteReturn doExecute(ApiContext context) {
		if (context.getApiExecutorObject().getApi().getOutput().getCache().isOn()&&context.isSuccessReadCache()) {
			return ExecuteReturn.builder().build(); 
		}
		if (context.getResponse().getErrorNo() == 0) {
			Api api=context.getApiExecutorObject().getApi();
			ApiRegulation lastSyncApiRegulation = api.lastSyncApiRegulation();
			if (lastSyncApiRegulation == null) {
				return ExecuteReturn.builder().code(-1).message("api["+api.getKey()+"]不存在同步执行规则,请检查").build();
			}
			List<DsName> dsNames = context.getResponse().getDsName();
			if (dsNames != null) {
				Output output = context.getApiExecutorObject().getApi().getOutput();
				context.getResponse().setMainDsKey(output.getMainOutputDsKey());
				Map<String, OutputDs> outputDsMap = output.outputDsMap();
				String lastSyncApiRegulationuid = lastSyncApiRegulation.getRegulation().uid();
				for (DsName dsName : dsNames) {
					int len=lastSyncApiRegulationuid.length() + 1;
					if (dsName.getName().length()<=len) {
						context.getResponse().clear(dsName.getName());
						continue;
					}
					String dsKey = dsName.getName().substring(len);
					if (outputDsMap.containsKey(dsKey)) {
						String reqTag=context.getRequest().getString(output.getReqTagKey(), "");//请求标记，用于返回结果集标记
						String actualDsKey=dsKey;
						if (ObjectUtil.isNotEmpty(reqTag)) {
							actualDsKey=reqTag+"."+dsKey;
						}
						Map<String, OutputParameter> map = output.outputParameterMap(dsKey);
						switch (dsName.getType()) {
						case page:
							PageObject<Object> pageObject = context.getResponse().pageTObject(dsName.getName());
							context.getResponse().clear(dsName.getName());
							pageObject.getList().forEach(d -> {
								fix(context.getApiExecutorObject().getApi(), d, map);
							});
							context.getResponse().resultObject(actualDsKey, pageObject);
							break;
						case list:
							List<Object> list = context.getResponse().listObject(dsName.getName());
							context.getResponse().clear(dsName.getName());
							list.forEach(d -> {
								fix(context.getApiExecutorObject().getApi(), d, map);
							});
							context.getResponse().resultObject(actualDsKey, list);
							break;
						case map:
							Object data = context.getResponse().dataObject(dsName.getName());
							context.getResponse().clear(dsName.getName());
							fix(context.getApiExecutorObject().getApi(), data, map);
							context.getResponse().resultObject(actualDsKey, data);
							break;
						default:
							break;
						}
						context.getResponse().getDsName(actualDsKey).setMainOutputDsKey(output.getMainOutputDsKey());
					} else {
						context.getResponse().clear(dsName.getName());
					}
				}
			}
			return ExecuteReturn.builder().build();
		}else {
			return ExecuteReturn.builder().code(-1).message(context.getResponse().getErrorInfo()).build();
		}
		
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void fix(Api api, Object dataObject, Map<String, OutputParameter> map) {
		if (dataObject instanceof Map) {
			Map data=(Map) dataObject;
			Map<String, Object> kv = new HashMap<String, Object>();
			data.keySet().forEach(e->{
				String key = api.getOutput().isToCamelCase() ? StrUtil.toCamelCase(String.valueOf(e)) : String.valueOf(e);
				OutputParameter outputParameter=map.get(key);
				if (outputParameter!=null) {
					Object v=data.get(e);
					if (ObjectUtil.isNull(v)) {
						kv.put(outputParameter.mapping(),outputParameter.getDefaultValue());
					}else {
						kv.put(outputParameter.mapping(), v);
					}
				}
			});
			map.keySet().forEach(k -> {
				OutputParameter outputParameter=map.get(k);
				if (!kv.containsKey(outputParameter.mapping())) {
					kv.put(outputParameter.mapping(),outputParameter.getDefaultValue());
				}
			});
			data.clear();
			data.putAll(kv);
		}
	}

	public static void main(String[] args) {
		String x = "890.99";
		System.out.println(x.substring("890".length() + 1));
	}
}
